package com.heima.comment.service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heima.apis.behavior.IBehaviorClient;
import com.heima.apis.user.IUserClient;
import com.heima.apis.wemedia.IWemediaClient;

import com.heima.comment.pojo.ArticleComment;
import com.heima.comment.pojo.ArticleLikesComment;
import com.heima.comment.service.CommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.redis.CacheService;
import com.heima.model.common.constants.HotArticleConstants;
import com.heima.model.common.dtos.app.LikesBehaviorDto;
import com.heima.model.common.dtos.comment.CommentDto;
import com.heima.model.common.dtos.comment.CommentLikeDto;
import com.heima.model.common.dtos.comment.CommentSaveDto;
import com.heima.model.common.dtos.common.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.mess.UpdateArticleMess;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.utils.thread.AppThreadLocalUtil;
import com.mongodb.client.result.DeleteResult;
import net.sf.jsqlparser.expression.DateTimeLiteralExpression;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.net.nntp.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.*;

@Service
public class CommentServiceImpl implements CommentService {
    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private IWemediaClient wemediaClient;
    @Autowired
    private IUserClient userClient;
    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private IBehaviorClient behaviorClient;
    /**
     * 保存评论
     * @param commentSaveDto
     * @return
     */
    @Override
    public ResponseResult save(CommentSaveDto commentSaveDto) {
        //检验参数
        if (commentSaveDto==null||commentSaveDto.getContent()==null||commentSaveDto.getArticleId()==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //检验是否登录
        String userId = AppThreadLocalUtil.getUser().getId().toString();
        if(userId.equals("0")|| userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //判断评论内容是否超过140字
        if(commentSaveDto.getContent().length()>140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"评论内容不能超过140字");
        }
        //进行文字垃圾检测
        boolean isTextScan=handleTextScan(commentSaveDto.getContent());
        if(!isTextScan) {
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"评论内容中包含违禁词,审核未通过");
        }
        ResponseResult user = userClient.getUser(userId);
        if(user.getCode()!=200){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"用户信息不匹配");
        }
        String jsonData = (String) user.getData();
        ApUser apUser = JSON.parseObject(jsonData, ApUser.class);
        //将评论数据保存到mongodb数据库中
        ArticleComment articleComment = ArticleComment
                .builder()
                .entryId(commentSaveDto.getArticleId())
                .content(commentSaveDto.getContent())
                .authorId(apUser.getId())
                .authorName(apUser.getName())
                .createdTime(new Date())
                .likes(0)
                .reply(0)
                .build();
        mongoTemplate.save(articleComment);
        //向使用kafka发消息给给mysql数据库更新评论数量
        UpdateArticleMess mess = new UpdateArticleMess();
        mess.setArticleId(commentSaveDto.getArticleId());
        mess.setType(UpdateArticleMess.UpdateArticleType.COMMENT);
        mess.setAdd(1);
        kafkaTemplate.send(HotArticleConstants.HOT_ARTICLE_SCORE_TOPIC, JSON.toJSONString(mess));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 分页显示文字评论内容
     * @param commentDto
     * @return
     */
    @Override
    public ResponseResult load(CommentDto commentDto) {
        //检验参数
        if (commentDto == null || commentDto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //获取当前用户id
        ApUser apUser = AppThreadLocalUtil.getUser();
        //以最小时间为查询条件，创建时间倒序，分页查询该文字所有评论
        Date minDate = new Date();
        minDate.setTime(Long.parseLong(commentDto.getMinDate()));
        Query query = Query.query(Criteria.where("entryId").is(commentDto.getArticleId()).and("createdTime").lt(minDate)).limit(10).with(Sort.by(Sort.Direction.DESC, "createdTime"));
        List<ArticleComment> articleComments = mongoTemplate.find(query, ArticleComment.class);
        for (ArticleComment articleComment : articleComments) {
            //判断当前用户是否点赞了该评论，如果没有点赞，则设置operation字段为null
            query = Query.query(Criteria.where("likesUserId").is(String.valueOf(apUser.getId())));
            List<ArticleLikesComment> articleLikesComments = mongoTemplate.find(query, ArticleLikesComment.class);
            if (articleLikesComments.size() == 0) {
                articleComment.setOperation(null);
            }
        }
        //将获取的结果返回给前端
        return ResponseResult.okResult(articleComments);
    }
    /**
     * 点赞评论功能
     * @param commentLikeDto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto commentLikeDto) {
        //检验参数
        if(commentLikeDto==null||commentLikeDto.getCommentId()==null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //判断用户是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if(apUser.getId().equals("0")|| apUser.getId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据文章id,获取该文章的所有信息
        Query query = Query.query(Criteria.where("id").is(commentLikeDto.getCommentId()));
        ArticleComment articleComment = mongoTemplate.findOne(query, ArticleComment.class);
        if(commentLikeDto.getOperation()==0){
            //点赞评论，设置评论表,likes字段+1
            articleComment.setLikes(articleComment.getLikes() + 1);
            //如果有用户点赞该评论，则将评论id和用户id存入评论点赞表中
            ArticleLikesComment articleLikesComment = ArticleLikesComment
                    .builder()
                    .likesUserId(String.valueOf(apUser.getId()))
                    .commentId(commentLikeDto.getCommentId())
                    .build();
            articleLikesComment = mongoTemplate.save(articleLikesComment);
            if(articleComment.getId()!=null){
                //评论点赞表保存记录成功，设置operation为0
                articleComment.setOperation((short) 0);
            }
            articleComment.setUpdatedTime(new Date());
            mongoTemplate.save(articleComment);
        }else{
            //取消点赞,文章评论表likes-1,删除文章点赞表中对应点赞用户的记录
            articleComment.setLikes(articleComment.getLikes() - 1);
            query = Query.query(Criteria.where("likesUserId").is(String.valueOf(apUser.getId())));
            mongoTemplate.remove(query,ArticleLikesComment.class);
            //如果该文章没有人点赞，则设置operation为null
            query=Query.query(Criteria.where("commentId").is(commentLikeDto.getCommentId()));
            List<ArticleLikesComment> articleLikesComments = mongoTemplate.find(query, ArticleLikesComment.class);
            if (articleLikesComments.size() == 0) {
                articleComment.setOperation(null);
            }
            articleComment.setUpdatedTime(new Date());
            mongoTemplate.save(articleComment);
        }

        //封装响应数据
        HashMap<String,Object> map=new HashMap<>();
        map.put("likes",articleComment.getLikes());
        return ResponseResult.okResult(map);
    }

    /**
     * 文本垃圾检测
     * @param comment
     * @return
     */
    private boolean handleTextScan(String comment) {
        boolean flag=true;
        if(StringUtils.isBlank(comment)){
            return flag;
        }
        try{
            //如果敏感词审核未通过直接返回未过审
            if(!handleSensitiveScan(comment)){
                return false;
            }
            //审核失败
            Map map = greenTextScan.greeTextScan(comment);
            if(map==null){
                return flag;
            }
            if(map.get("suggestion").equals("block")){
                flag=false;
                return flag;

            }
            //不确定需要人工审核
            if(map.get("suggestion").equals("review")){
                flag=false;
                return flag;

            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 调用mapper获取所有违禁词
     * @param comment
     * @return
     */
    private boolean handleSensitiveScan(String comment) {
        boolean flag=true;
        String jsonData= (String) wemediaClient.sensitives().getData();
        List<WmSensitive> wmSensitives=JSON.parseArray(jsonData, WmSensitive.class);
        if(wmSensitives==null){
            return flag;
        }
        //如果评论中包含违禁词直接返回false
        for (WmSensitive wmSensitive : wmSensitives) {
            if(comment.contains(wmSensitive.getSensitives())){
                flag=false;
                return flag;
            }
        }
        return flag;
    }

}
